<template>
  <div class="filterPanel" :style="curStyle">
    <el-form :label-width="labelWidth" :label-position="labelPosition" :inline="true">
      <draggable
        v-model="rows"
        :sort="true"
        :group="filterGroup"
        :move="checkIsMove"
        draggable=".item"
        @add="add"
        @end="endSort"
        @remove="remove"
      >
        <transition-group class="draggable-group">
          <el-form-item
            v-for="i in rowList"
            :id="i.id"
            :key="i.key"
            :label="i.title"
            type="item"
            :class="'item' + (curKey == i.key ? ' chiose' : '')"
          >
            <a @click.stop="chiose(i)">
              <component :is="i.key" :key="i.Id" :page-id="pageId" :content-width="bodyWidth" v-bind="i" @edit="edit" />
            </a>
            <div class="optBtn">
              <el-button type="primary" size="mini" icon="el-icon-edit" circle @click="edit(i.id)" />
              <el-button type="danger" size="mini" icon="el-icon-delete" circle @click="drop(i)" />
            </div>
          </el-form-item>
        </transition-group>
      </draggable>
    </el-form>
    <editControl
      :id="curId"
      :visible.sync="visible"
      :content-width="bodyWidth"
      :page-id="pageId"
      @close="close"
    />
  </div>
</template>

<script>
import draggable from 'vuedraggable'
import { GetLayout } from '@/customForm/api/page'
import { layoutControl } from '@/customForm/config/formConfig'
import * as layoutApi from '@/customForm/api/pageLayout'
import editControl from '../pageEdit/editControl.vue'
import Vue from 'vue'
export default {
  components: {
    draggable,
    editControl
  },
  props: {
    id: {
      type: String,
      default: null
    },
    pageId: {
      type: String,
      default: null
    },
    item: {
      type: Object,
      default: null
    },
    width: {
      type: Number,
      default: null
    },
    children: {
      type: Array,
      default: null
    },
    contentWidth: {
      type: Number,
      default: null
    }
  },
  data() {
    return {
      rowList: [],
      visible: false,
      rows: [],
      curStyle: {
        textAlign: 'left'
      },
      labelWidth: '120px',
      labelPosition: 'right',
      bodyWidth: null,
      isInit: false,
      curId: null,
      curKey: null,
      filterGroup: {
        name: 'filter',
        pull: true,
        put: true
      }
    }
  },
  computed: {},
  watch: {
    children: {
      handler(val) {
        this.reset()
      },
      immediate: true
    },
    width: {
      handler(val) {
        if (val && this.contentWidth) {
          this.init()
        }
      },
      immediate: true
    },
    'item.LabelPosition': {
      handler(val) {
        this.labelPosition = val ?? 'right'
      },
      immediate: false
    },
    'item.LabelWidth': {
      handler(val) {
        this.labelWidth = val ? val + 'px' : '120px'
      },
      immediate: false
    },
    contentWidth: {
      handler(val) {
        if (val && this.width) {
          this.init()
        }
      },
      immediate: true
    }
  },
  mounted() {
  },
  methods: {
    chiose(item) {
      if (this.curKey === item.key) {
        this.curKey = null
      } else {
        this.curKey = item.key
      }
    },
    init() {
      let width = 0
      if (this.width === 23) {
        width = Math.round(this.contentWidth * 2 / 3) - 12
      } else {
        width = Math.round(this.contentWidth / this.width) - 12
      }
      this.curStyle.width = width + 'px'
      this.bodyWidth = width
    },
    remove(e) {
      const index = this.rowList.findIndex(c => c.id === e.item.id)
      if (index !== -1) {
        this.rowList.splice(index, 1)
      }
    },
    close(isRefresh, id, data, type) {
      if (isRefresh && type === 4) {
        this.refreshDataTable(id)
      } else if (isRefresh) {
        const row = this.rowList.find(c => c.id === id)
        row.title = data.Name
        row.width = data.WidthRatio
        row.height = data.HeightGrid
        row.show = data.Show
        if (row.type === 0) {
          const config = data.ControlConfig.Statistics
          row.item = {
            Icon: config.Icon,
            ValueStyle: config.ValueStyle,
            FontSize: config.FontSize,
            Color: config.Color,
            IsCenter: config.IsCenter,
            IsConfig: config.FormId != null && config.Select != null
          }
        } else if (row.type === 1) {
          const config = data.ControlConfig.Chart
          row.item = {
            ChartType: config.ChartType,
            Title: config.Title,
            YAxis: config.YAxis,
            XAxis: config.XAxis,
            MarkLine: config.MarkLine,
            Legend: config.Legend,
            IsConfig: config.Selects != null && config.Selects.length > 0 && config.GroupBy != null && config.GroupBy.length > 0
          }
        } else if (row.type === 5) {
          row.item = data.ControlConfig.Layout ?? {}
        } else if (row.type === 6) {
          row.item = data.ControlConfig.ControlSet ?? {}
        } else if (row.type === 3) {
          row.item = data.ControlConfig.Search ?? {}
        } else if (row.type === 2) {
          const config = data.ControlConfig.CensusTable
          row.item = {
            IsConfig: config.Selects != null && config.Selects.length > 0
          }
        }
      }
    },
    async refreshDataTable(id) {
      const res = await GetLayout(id, true)
      const row = this.rowList.find(c => c.id === id)
      row.title = res.Name
      row.width = res.WidthRatio
      row.height = res.HeightGrid
      row.show = res.Show
      row.item = res.Table ?? {}
    },
    edit(id) {
      this.curId = id
      this.visible = true
    },
    add(e) {
      const type = e.item.getAttribute('type')
      const id = e.item.id
      let index
      if (type === 'control') {
        index = this.rows.findIndex(c => c.Id === id && c.itemId == null)
      } else {
        index = this.rows.findIndex(c => c.itemId === id)
      }
      this.addControl(index)
    },
    async addControl(index) {
      const t = this.rows[index]
      if (t == null) {
        return
      } else if (t.itemId != null) {
        const res = await layoutApi.Move(t.itemId, this.id, true)
        t.pid = this.id
        const item = this.format(res)
        this.rowList.push(item)
        this.saveSort()
      } else {
        const add = {
          PageId: this.pageId,
          ControlId: t.Id,
          Sort: index,
          ParentId: this.id
        }
        const res = await layoutApi.Add(add)
        this.rows[index] = {
          Id: add.ControlId,
          itemId: res.Id,
          pid: this.id,
          Classify: res.Classify
        }
        const item = this.format(res)
        this.rowList.push(item)
        this.saveSort()
      }
    },
    format(control) {
      const t = {
        key: 'c_' + control.Id,
        id: control.Id,
        title: control.Name,
        width: control.WidthRatio,
        height: control.HeightGrid,
        show: control.Show,
        type: control.ControlType,
        code: control.Code,
        item: null,
        children: null
      }
      if (t.type === 0) {
        t.item = control.Statistics
      } else if (t.type === 1) {
        t.item = control.Chart ?? {}
      } else if (t.type === 4) {
        t.item = control.Table ?? {}
      } else if (t.type === 5) {
        t.item = control.Layout ?? {}
        if (control.Children != null && control.Children.length > 0) {
          t.children = control.Children.map(a => this.format(a))
        }
      } else if (t.type === 6) {
        t.item = control.ControlSet ?? {}
      } else if (t.type === 3) {
        t.item = control.Search ?? {}
      } else if (t.type === 2) {
        t.item = control.CensusTable ?? {}
      }
      Vue.component(t.key, function(resolve, reject) {
        require(['@/' + control.ControlPath + '.vue'], resolve)
      })
      return t
    },
    checkIsMove(e) {
      if (e.relatedContext == null) {
        return false
      }
      const el = e.draggedContext.element
      const name = e.relatedContext.component.$attrs.group.name
      if (el.Classify === '02' && el.Id === layoutControl.row) {
        return name === 'page' || name === 'tab' || name === 'card'
      } else if (el.Classify === '04') {
        return name === 'filter'
      } else {
        return name === 'page' || name === 'row' || name === 'tab' || name === 'card'
      }
    },
    reset() {
      if (this.item) {
        this.labelPosition = this.item.LabelPosition
        this.labelWidth = this.item.LabelWidth + 'px'
        this.curStyle.textAlign = this.item.FormAlign ?? 'left'
      } else {
        this.labelPosition = 'right'
        this.labelWidth = '120px'
        this.curStyle.textAlign = 'left'
      }
      if (this.children != null && this.children.length > 0) {
        const rows = []
        this.rowList = this.children.map(e => {
          const t = this.format(e)
          rows.push({
            Id: e.ControlId,
            itemId: e.Id,
            pid: this.id,
            Classify: e.Classify
          })
          return t
        })
        this.rows = rows
      } else {
        this.rowList = []
        this.rows = []
      }
    },
    async saveSort() {
      let i = 0
      const list = this.rowList.map(c => {
        i = i + 1
        return {
          Id: c.id,
          Value: i
        }
      })
      await layoutApi.SaveSort(list)
    },
    endSort(e) {
      if (this.rowList.length <= 1 || e.newIndex === e.oldIndex) {
        return
      }
      const arr = this.rowList
      const t = arr[e.newIndex]
      const old = arr[e.oldIndex]
      arr[e.newIndex] = old
      arr[e.oldIndex] = t
      this.rowList = [].concat(arr)
      this.saveSort()
    },
    drop(item) {
      const title = '确认删除控件 ' + item.title + '?'
      const that = this
      this.$confirm(title, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        that.submitDrop(item)
      })
    },
    async submitDrop(item) {
      await layoutApi.Delete(item.id)
      this.$message({
        type: 'success',
        message: '删除成功!'
      })
      this.dropItem(item)
    },
    dropItem(item) {
      const index = this.rows.findIndex(c => c.itemId === item.id)
      if (index !== -1) {
        this.rows.splice(index, 1)
      }
      this.rowList = this.rowList.filter(c => c.id !== item.id)
      this.saveSort()
    }
  }
}
</script>
<style lang="css" scoped>
.el-form {
  background-color: #fff;
}
.dark .el-form {
  background-color: transparent !important;
}
.draggable-group {
  width: 100%;
  min-height: 60px;
  display: inline-block;
}
.header .icon {
    font-size: 16px;
}
.header span {
    margin-left: 10px;
}
.chiose {
    border: 1px solid #1682e6
}

.item {
    cursor: pointer;
    margin-bottom: 10px;
    margin-top: 10px;
}

.item .optBtn {
    position: absolute;
    top: -34px;
    display: none;
}

.chiose .optBtn {
    display: block !important;
}
</style>
